﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MIO.Client.Util
{
    public interface ILog
    {
        void i(String msg);
        /**
         * PROMPT
         * 
         * @param msg
         */
        void p(String msg);

        /**
         * DEBUG
         * 
         * @param msg
         */
        void d(String msg);

        /**
         * WARN
         * 
         * @param msg
         */
        void w(String msg);

        /**
         * ERROR
         * 
         * @param msg
         */
        void e(String msg, Exception e);
        /**
         * FETAL
         * 
         * @param msg
         */
        void f(String msg, Exception ex);
    }
    public class Log
    {
        /** 日志输出级别 */
        public const int INFO = 1, PROMPT = 2, DEBUG = 3, WARN = 4, ERROR = 5, FETAL = 6;

        private int logLevel = -1;

        private ILog logObj = null;

        private static Log instance = null;

        public static Log getInstance()
        {
            if (instance == null)
                instance = new Log();
            return instance;
        }

        public void setLog(ILog logObj)
        {
            this.logObj = logObj;
        }

        private Log() { }


        public int getLogLevel()
        {
            return logLevel;
        }
        public Log setLogLevel(int logLevel)
        {
            this.logLevel = logLevel;
            return this;
        }

        /**
         * INFO
         * 
         * @param msg
         */
        public static void i(String tag, String msg)
        {
            i(tag, msg, null);
        }
        public static void i(String tag, String msg, Exception ex)
        {
            Log.getInstance().log(msg, Log.INFO, ex);
        }

        /**
         * PROMPT
         * 
         * @param msg
         */
        public static void p(String tag, String msg)
        {
            p(tag, msg, null);
        }
        public static void p(String tag, String msg, Exception ex)
        {
            Log.getInstance().log(msg, Log.PROMPT, ex);
        }

        /**
         * DEBUG
         * 
         * @param msg
         */
        public static void d(String tag, String msg)
        {
            de(tag, msg, null);
        }

        public static void d(string tag,string msg,params string[] args)
        {
            de(tag, string.Format(msg, args), null);
        }

        public static void de(String tag, String msg, Exception ex)
        {
            Log.getInstance().log(msg, Log.DEBUG, ex);
        }

        /**
         * WARN
         * 
         * @param msg
         */
        public static void w(String tag, String msg)
        {
            w(tag, msg, null);
        }
        public static void w(String tag, String msg, Exception ex)
        {
            Log.getInstance().log(msg, Log.WARN, ex);
        }

        /**
         * ERROR
         * 
         * @param msg
         */
        public static void e(String tag, String msg)
        {
            e(tag, msg, null);
        }
        public static void e(String tag, String msg, Exception ex)
        {
            Log.getInstance().log(msg, Log.ERROR, ex);
        }

        /**
         * FETAL
         * 
         * @param msg
         */
        public static void f(String tag, String msg)
        {
            f(tag, msg, null);
        }
        public static void f(String tag, String msg, Exception ex)
        {
            Log.getInstance().log(msg, Log.FETAL, ex);
        }

        /**
         * 日志输出.
         * 
         * @param msg
         * @param level
         */
        public void log(String msg, int level)
        {
            this.log(msg, level, null);
        }

        /**
         * 日志输出.
         * 
         * @param msg
         * @param level
         */
        public void log(String msg, int level, Exception ex)
        {
            String lv = "";
            switch (level)
            {
                case INFO:
                    lv = "INFO";
                    logObj?.i(msg);
                    break;
                case PROMPT:
                    lv = "PROMPT";
                    logObj?.p(msg);
                    break;
                case DEBUG:
                    lv = "DEBUG";
                    logObj?.d(msg);
                    break;
                case WARN:
                    lv = "WARN";
                    logObj?.w(msg);
                    break;
                case ERROR:
                    lv = "ERROR";
                    logObj?.e(msg, ex);
                    break;
                case FETAL:
                    lv = "FETAL";
                    logObj?.f(msg, ex);
                    break;
            }

            if (level > logLevel)
            {
                String txt = " " + lv + " - " + msg + (ex == null ? "" : "(" + ex.Message + ")") + " [" + (DateTime.Now.ToLocalTime()) + "]\r\n";
                Console.WriteLine(txt);

                if (ex != null)
                    ex.ToString();
            }
        }

    }
}
